/**
 * 项目名称:
 *
 * @Author: 夏国倩
 * @Date: 2023/10/12 15:19
 * @Copyright
 */
package multithreading;
/*
以下程序使用线程同步机制保证数据安全
 */
public class ThreadTest14 {
    public static void main(String[] args) {
        //创建公共的账户
        Account3 act=new Account3("actno-001",5000);
        //创建线程对同一个账户取款
        Thread t1 = new Thread(new Processor14(act));
        Thread t2 = new Thread(new Processor14(act));
        t1.start();
        t2.start();
    }
}
//取款线程
class  Processor14 implements Runnable{
    //账户
    Account3 act;
    public Processor14(Account3 act){
        this.act=act;
    }
    @Override
    public void run() {
        act.withdraw(1000.0);
        System.out.println("取款1000.00，余额："+act.getBalance());
    }
}
//账户
class Account3{
    private String actno;
    private double balance;

    public Account3() {
    }

    public Account3(String actno, double balance) {
        this.actno = actno;
        this.balance = balance;
    }

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
    //对外提供一个取款的方法
    //synchronized关键字添加到成员方法上，线程拿走的也是this的对象锁
    public synchronized void withdraw(double money){
        //把需要重复的代码放到同步语句块中
        /*
        原理：t1线程和t2线程
        t1线程执行到此，遇到synchronized关键字，就会去找this的对象锁
        如果找到对象锁，则进入同步语句块中执行程序，当同步语句块中的代码执行结束之后，t1线程归还
        this对象锁
        在t1的同步语句块执行过程中，如果t2线程也过来执行以下代码，也遇到synchronized关键字，所以也去找This的对象锁
        ，但是该对象锁t1锁持有，只能在这等待this对象的归还
         */
        double after=balance-money;
        //延迟
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //更新
        this.setBalance(after);
    }
}